package com.apestech.framework.xml.pub;

import java.util.ArrayList;

import org.apache.log4j.Logger;
import com.alibaba.druid.pool.DruidDataSource;
import com.apestech.formwork.stream.ListStream;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.json.JSONSerialization;
import com.apestech.framework.util.StringUtil;

/**
 * XML相关功能实现类
 * @author hupo
 *
 */
public class XmlService extends StringUtil {
	
	private static final Logger logger = Logger.getLogger(XmlService.class);
	
	private JSONArray getCBData(String CB, int num){
		JSONArray cb=new JSONArray();
		for(int i=0; i<=num; i++){
			JSONObject map=new JSONObject();
			map.put(CB+"CKEY", i);
			cb.add(map);
		}
		return cb;
	}
	
	public void execSql(String threadName, String sql, DruidDataSource ds, String plid) throws Exception{
		String esql=sql+" and plid like '"+plid+"%' ";  //and rownum<11
		//esql=esql+" AND DSFSPID IN ('000163328889','000163328890','000163328891','000163328892','000163328893','000163328894','000163328895','000163328896','000163328897','000163328898','000163328899','000163328900','000163328901') ";
		/*SqlTemplate cn=new SqlTemplate(ds);
		cn.prepareStatement(esql);
		String filename="d:/"+threadName+plid;  //+".txt";
		final SqlResultSet rs=new SqlResultSet(cn.executeQuery(esql));
		System.out.println(esql);
		
		WriteArrayStream write=new WriteArrayStream(rs);
		write.setMaxSize(UnitUtil.KB2B(100));
		write.write(new ArrayObjectStreamHander(rs));
		/*write.read(1, new ReadBufferFileCallBackHandler(){
			public boolean read(String text, int index) throws Exception {
				System.out.println(index);
				System.out.println(text);
				return true;
			}
		});*/
		
		/*write.read(1, new ReadBufferFileCallBackHandler(){
			public boolean read(String text, int index) throws Exception {
				System.out.println(index);
				System.out.println(text);
				return true;
			}
		});
		*/
		 
	}
		
		
		//final BufferFile file=new BufferFile(filename);
		/*file.write(new SqlResultSetWriteFile(rs){
			protected String write(SqlResultSet rs, int index) throws Exception {
				/*String[] list=rs.getColumns();
				int len=list.length;
				StringBuilder sb=new StringBuilder();
				sb.append("{");
				for(int i=0; i<len; i++){
					String key=list[i];
					Object ob=rs.getObject(key);
					if(i>0){
						sb.append(",");
					}
					if(ob==null){
						sb.append("\""+key+"\":null");
					} else {
						String classname=ob.getClass().getName();
						switch(classname){
							case "java.lang.String":
								sb.append("\""+key+"\":\""+ob+"\"");
								break;
							case "java.math.BigDecimal":
								sb.append("\""+key+"\":"+ob);
								break;
							case "java.sql.Timestamp":
								//System.out.println("\""+key+"\":\""+ob+"\"");
								sb.append("\""+key+"\":\""+ob+"\"");
								break;
							default:
								System.out.println(classname);
								break;
						}
						
						
					}
				}
				sb.append("}");
				//System.out.println(JSON.parseObject(sb.toString(), JSONObject.class).toString());
				return sb.toString(); //JSON.toJSONString(rs.toRowJson());
				*/
				//return JSON.toJSONString(rs.toRowJson());
			//}
			
		//});
		
		
	//}	

	public void testo() throws Exception{
		String filename="d:/索引拼音";
		ListStream list=new ListStream(filename);
		//list.setKeyField("SPMC");
		//list.setPinyinField("SPMC");
		//list.setKeyLength(1);
		System.out.println(list.toString());
		System.out.println(list.getFetchSize());
		//System.out.println(list.getPageAsString(1, 5));
		//System.out.println(list.getPageAsJSONArray(1, 5));
		list.bof();
		while(list.next()){
			System.out.println(list.getText());
		}
		System.out.println(list.getIndex("名牌散热器/水箱JSS06244A"));
		System.out.println(list.toString());
		
		JSONSerialization json=new JSONSerialization();
		json.add("success", true);
		json.add("msg", "hello world!");
		json.add("list", list.getPageAsByte(1, 10));
		json.fini();
		System.out.println(json.toString());
	}
	
	
	public void getMenu() throws Exception{
		//String filename="d:/xmlm/粤YCP062_2017-11-27.png";
		//FileUtil.saveTxtFile("", new String(filename.getBytes("UTF-8"),  "utf-8"));
		XmlToJson xml=new XmlToJson();
		JSONObject xmlmap=xml.xmlToJsonAttrJson("D:/xmlM/MENU_TREE.XML").getJSONObject("YuanYuanSoftware");
		String database=xmlmap.getJSONObject("database").getString("node_text");
		String sql=xmlmap.getJSONObject("sql").getString("node_text");
		JSONArray list=getSourceData(database, sql);
		logger.info(getTreeData(list, xmlmap.getJSONObject("content")));
	}
	
	/**
	 * 数据MAPPING中获取输出ID
	 * @param key
	 * @param xmlmap
	 * @return
	 * @throws Exception
	 */
	private String getOutId(String key, JSONObject xmlmap) throws Exception{
		JSONObject amap=null;
		amap=xmlmap.getJSONObject(key).getJSONObject("node_attr");
		if(amap!=null){
			if(amap.get("alias")!=null){
				key=amap.getString("alias");
			}
		}
		return key;
	}
	
	/**
	 * 获取XML中结点文本真实值
	 * @param text
	 * @param params
	 * @return
	 */
	private String getText(String text, Object... params){
		ArrayList<String> list=getBatisVariableList(text);
		if(list==null){
			return text;
		}
		int ilen=list.size();
		for(int i=0;i<ilen;i++){
			String Key=list.get(i);
			Object value = null;
			if(params!=null){
				int plen=params.length;
				for (int p=0;p<plen;p++){
					JSONObject map=(JSONObject) params[p];
					if(map!=null){
						value=map.get(Key);
						if(value==null){
							value="";
						}
						break;
					}
				}
			}
			text=replaceBatisVariable(text, Key, value);
		}
		return text;
	}
	
	/**
	 * 树型结构XML解析
	 * @param list
	 * @param xmlmap
	 * @return
	 * @throws Exception
	 */
	public JSONArray getTreeData(JSONArray list, JSONObject xmlmap) throws Exception{
		JSONArray rlist=null;
		if(rlist==null){
			rlist=new JSONArray();
		}
		
		String childname=xmlmap.getJSONObject("node_attr").getString("childname");
		String id_value=xmlmap.getJSONObject("id").getString("node_text");
		String id=getOutId("id", xmlmap);
		
		String pid_value=xmlmap.getJSONObject("pid").getString("node_text");
		String nullable=xmlmap.getJSONObject("pid").getJSONObject("node_attr").getString("nullable");
		String pid=getOutId("pid", xmlmap);
		
		int len=list.size();
		for(int i=0; i<len; i++){
			JSONObject mxmap= (JSONObject) list.get(i);
			JSONObject map=new JSONObject();
			int flen=xmlmap.size();
			ArrayList<String> flist=xmlmap.getKeylist();
			for(int f=0; f<flen; f++){
				String key=flist.get(f);
				if(!"node_attr".equals(key)){
					String text=xmlmap.getJSONObject(key).getString("node_text");
					JSONObject attrmap=xmlmap.getJSONObject(key).getJSONObject("node_attr");
					key=getOutId(key, xmlmap);
					text=getText(text, mxmap);
					String valuetype="";
					if(attrmap!=null){
						valuetype=getString(attrmap.getString("valuetype"));
					}
					if("boolean".equals(valuetype)){
						map.put(key, Boolean.parseBoolean(text));
					} else {
						map.put(key, text);
					}
				}
			}
			boolean isFirstNode=false;
			String pidValue=getText(pid_value, mxmap);
			if("1".equals(nullable)){
				if("".equals(pidValue)){
					isFirstNode=true;
				}
			} else {
				if(pidValue.equals(getText(id_value, mxmap))){
					isFirstNode=true;
				}
			}
			if(isFirstNode){
				rlist.add(map);
			} else {
				setTreeValue(rlist, id, getText(pid_value, mxmap), map, id_value, childname);
			}
			map=null;
		}
		return rlist;
	}
	
	/**
	 * 设置树结点部分的列表数据
	 * @param list
	 * @param id
	 * @param keyvalue
	 * @param map
	 * @param id_value
	 * @param childname
	 */
	private void setTreeValue(JSONArray list, String id, String keyvalue, JSONObject map, String id_value, String childname){
		int len=list.size();
		for(int i=0; i<len; i++){
			JSONObject mxmap=(JSONObject) list.get(i);
			String idvalue=mxmap.getString(id);
			if(keyvalue.indexOf(idvalue)>=0){
				JSONArray mxlist=(JSONArray) mxmap.get(childname);
				if(keyvalue.equals(idvalue)){
					if(mxlist==null){
	    				mxlist=new JSONArray();
	    			}
					mxlist.add(map);
        			mxmap.put(childname, mxlist);
				} else {
					setTreeValue(mxlist, id, keyvalue, map, id_value, childname);
				}
			}
		}
	}
	
	/**
	 * 执行SQL方式生成XML文件
	 * @param filename String 源XML对应带路径的文件名
	 * @param database String XML模板内定函数,与SRPING里配置的数据库关键字一致
	 * @param sql      String 执行SQL
	 * @param savedir  String 文件保存目录,可通过获取内定系统配置参数来做为内部功能的入口参数
	 * @return
	 * @throws Exception
	 */
	public void writeFromSql(String filename, String database, String sql, String savedir) throws Exception{
		JSONArray alist=getSourceData(database, sql);
		writeFromArray(alist, filename, database, savedir);
	}
	
	/**
	 * 执行SQL方式生成XML文件
	 * @param alist    JSONArray 生成XML对应的外部数据列表
	 * @param filename String 源XML对应带路径的文件名
	 * @param database String XML模板内定函数,与SRPING里配置的数据库关键字一致
	 * @param savedir  String 文件保存目录,可通过获取内定系统配置参数来做为内部功能的入口参数
	 * @return
	 * @throws Exception
	 */
	public void writeFromArray(JSONArray alist, String filename, String database, String savedir) throws Exception{
		XmlConfig xml=new XmlConfig();
		try {
			String mode=getWriteMode(getSource(database, filename, xml));				
			if("SINGLE".equals(mode)){
				xml.setSysText(null);
				xml.createXml(alist, savedir);
			} else {
				int len=alist.size();
				for(int i=0; i<len; i++){
					JSONArray list=new JSONArray();
					JSONObject mxmap=(JSONObject) alist.get(i);
					xml.getSysmap();
					xml.setSysText(mxmap);
					list.add(mxmap);
					xml.createXml(list, savedir);
				}
			}
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
			xml=null;
		}
	}
	
	/**
	 * 获取源XML相关基础信息
	 * @param filename String 源XML对应带路径的文件名
	 * @param database String XML模板内定函数,与SRPING里配置的数据库关键字一致
	 * @param xml XmlSysConfig
	 * @return
	 * @throws Exception
	 */
	private JSONObject getSource(String filename, String database, XmlConfig xml) throws Exception{
		JSONObject inputmap=new JSONObject();
		try {
			inputmap.put("dataBase", database);
			JSONObject xmlmap=xml.getSourceJson(filename);
			xml.addSysMap(inputmap);
			return xmlmap;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
			inputmap=null;
		}
	}
	
	/**
	 * 获取XML对应类型
	 * @param xmlmap JSONObject 源XML结点JSON
	 * @return "SINGLE":所有数据集中写一个XML; "MUTI":每一行数据即为一个XML
	 * @throws Exception
	 */
	private String getWriteMode(JSONObject xmlmap) throws Exception{
		JSONObject attrmap=xmlmap.getJSONObject("content").getJSONObject("node_attr");
		if(attrmap!=null && attrmap.get("forWhile")!=null){
			return "SINGLE";
		} else {
			return "MUTI";
		}
	}
	
	/**
	 * 测试暂用,会调整为从外部查询之后再传入数据模式
	 * @param database String
	 * @param sql      String
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("resource")
	private JSONArray getSourceData(String database, String sql) throws Exception{
		String username="testerp";
		String password="yysoft";
		if("SYS".equals(database)){
			username="testsys";
			password="yysoft";
		}
		DruidDataSource ds=new DruidDataSource();
		ds = new DruidDataSource();
		ds.setDriverClassName("oracle.jdbc.driver.OracleDriver"); 
		ds.setUrl("jdbc:oracle:thin:@10.2.0.55:1521:orcl");
		ds.setUsername(username);
		ds.setPassword(password);
		ds.setInitialSize(5);
		ds.setMinIdle(1); 
		ds.setMaxActive(10);  
		ds.setFilters("stat");  
		ds.setPoolPreparedStatements(false);
		//JdbcTemplate cn=new JdbcTemplate(ds);
		//return JSON.toJSONArray(cn.queryForList(sql));
		return null;
	}
	
}
